﻿// Zmienne "globalne" w aplikacji *****
var ctxMain = null; // główny kontekst dla canvasa
var gameWidth = 800; // szerokosc pola do gry
var gameHeight = 800; // wysokosc pola do gry
var snakesNumber = 1;
var winningTime = 6; // czas jaki pozostal do wyswietlania zwycieskiego wyniku
var displayingWinnerStarted = true; // rozpoczęcie wyświetlanie zwycięzcy
var displayingWinner = false; // czy wynik jest wyswietlany (potrzebne w klasie snake)
var winnerSnake; // waz ktory wygral runde
var goal = 10; // ilosc punktow do osiagniecia w danej rozgrywce
var textCanvas = null;
var ctx = null;
var bonusCanvas = null;
var ctxBonus = null;
var bonusInterval = 5000; // czas co ktory rysowany jest bonus
var snakes; // tablica wezykow
var colisionTable = [[]]; // tablica dwuwymiarowa w ktorej znajduja sie informacje czy dany pixel zostal juz przez jakis wezyk przejechany
var deadSnakes = [];// lista numerow wezy którzy nie zyja w danej rundzie
var fps = 40;
var roundFlyingTime = 2; // ile sekund wezyk lata po wystartowaniu nowej rundy

//po uruchomieniu strony wykonaj: 
function LoadGame() {
    // jezeli jakies pole nie czeka na wcisniecie klawisza
    if ($('.chooseKey').length == true) {
        return;
    }
    // zaladowanie graczy
    LoadPlayers();
    if (snakesNumber < 1) {
        alert("Wybierz conajmniej jednego gracza");
        return;
    }

    // warstwa z tekstem
    textCanvas = document.createElement("canvas");
    textCanvas.width = gameWidth;
    textCanvas.height = gameHeight;
    ctx = textCanvas.getContext("2d");

    // Sprawdź, czy przeglądarka obsługuje element Canvas
    var canvas = document.getElementById('gameCanvas');
    canvas.width = gameWidth;
    canvas.height = gameHeight;
    if (!canvas.getContext) { return; }
    ctxMain = canvas.getContext('2d');

    // aktywuj diva z gra i deaktywuje diva z menu
    document.getElementById("gameDiv").style.display = "block";
    document.getElementById("menuDiv").style.display = "none";
    // event listener dla klikniecia na przycisk powrotu - przeladowanie strony
    $("#back").click(function () { window.location.reload(); });

    InitializeColisionTable();
    InitializeBonuses();
    StartNewRound();
    StartDrawingLoop();
    // Nasłuchiwanie  klawiatury 
    document.addEventListener("keydown", KeyDown, false);
    document.addEventListener("keyup", KeyUp, false);
}

// utworzenie wezykow
function LoadPlayers() {
    var fields = [];
    snakesNumber = $('.playerReadyRow').length;
    snakes = new Array(snakesNumber);
    var i = 0;
    // dla kazdego wiersza z graczem
    $('.playerReadyRow').each(function () {
        fields = []; // wyczyszczenie tablicy

        //pobieranie wartosci kazdego pola
        $(this).children().each(function () {
            fields.push($(this).text());
        });
        fields.push($(this).css('color'));

        // stworzenie nowego snake
        snakes[i] = new Snake(fields[0], fields[1], fields[6], fields[4], fields[5]);
        i++;
    });
    SetScoreData();
}

// utworzenie tablicy i uzupelnienie zerami talbicy kolizji
function InitializeColisionTable() {
    colisionTable = new Array(gameHeight);
    for (var i = 0; i < gameHeight; i++) {
        colisionTable[i] = new Array(gameWidth);
    }
}

function CleanColisionTable(){
    for (var i = 0; i < gameHeight; i++) {
        for (var j = 0; j < gameWidth; j++) {
            colisionTable[i][j] = undefined;
        }
    }
}

// na panelu z wynikami dodajemy nazwy graczy, liczbe ich punktow (poczatkowo 0) oraz wynik ktory musi byc osiagniety
function SetScoreData() {
    // wynik do osiagniecia
    if (snakesNumber > 2) {
        goal = (snakesNumber - 1) * 10;
    }
    $('#goalScore').text(goal);
    // gracze
    for (var i = 0; i < snakesNumber; i++) {
        $('#playersScoreTable > tbody:last').append('<tr style=\'color:' + snakes[i].color + '\'><td>' + snakes[i].name + '</td><td id=\'points' + i + '\'>' + snakes[i].points + 
            '</td><td id=\'roundPoints' + i + '\' class=\'roundPoints\'></td></tr>');
    }
    ChangeGoalColor();
}

function StartDrawingLoop() {
    setInterval(DrawGameWorld, 1000 / fps);
    setInterval(GenerateBonus, bonusInterval);
}

// Funkcja rysująca świat gry *****
function DrawGameWorld() {
    ctxMain.clearRect(0, 0, gameHeight, gameWidth);

    // przesunięcie wszyskich węży
    for (var i = 0; i < snakesNumber; i++) {
        var snake = snakes[i]; // bieżący wąż

        if (snake.alive) {
            snake.move();
        }
        ctxMain.drawImage(snake.canvas, 0, 0);

        // jezeli wezyk umiera
        if (snake.dying) {
            deadSnakes.push(snake.number);
            snake.dying = false;
            UpdatePoints();
        }
    }

    // sprawdzenie ile graczy pozostało (jezeli niż 2 to restart rundy)
    if ((snakesNumber != 1 && deadSnakes.length >= snakesNumber - 1) || (snakesNumber == 1 && deadSnakes.length == 1)) {
        if (winningTime) {
            if (!CheckGameEnd()) {
                if (displayingWinnerStarted) {
                    FindRoundWinner();
                    displayingWinner = true;
                    for (var i = 0; i < 6; i++)
                        setTimeout(function () { winningTime -= 1; }, 1000 * i);
                    displayingWinnerStarted = false;
                }
                DrawWinningText();
            }
        } else {
            StartNewRound();
            displayingWinnerStarted = true;
            winningTime = 6;
            displayingWinner = false;
        }
    }
    DrawBonuses();
    ctxMain.drawImage(bonusCanvas, 0 ,0);
}

function DrawWinningText() {
    ctx.clearRect(0, 0, gameWidth, gameHeight);

    ctx.fillStyle = "rgba(0, 0, 0, 0.2)";
    ctx.fillRect(0, gameHeight / 2 - 50, gameWidth, 100);

    ctx.fillStyle = winnerSnake.color;
    ctx.font = 'italic bold 30px sans-serif';
    ctx.textBaseline = 'bottom';
    ctx.fillText(winnerSnake.name + ' wins this round!', 20, gameHeight / 2 + 15);

    //ctx.fillStyle = 'blue';
    //ctx.fillRect(gameWidth - 200, gameHeight / 2 - 25, 200, 50);

    ctx.fillStyle = 'white';
    ctx.font = 'italic bold 20px sans-serif';
    ctx.fillText('To next round: ' + (winningTime-1), gameWidth - 180, gameHeight / 2 + 15);

    ctxMain.drawImage(textCanvas, 0, 0);
}

function DrawEndText() {
    ctx.clearRect(0, 0, gameWidth, gameHeight);

    ctx.fillStyle = "rgba(0, 0, 0, 0.4)";
    ctx.fillRect(0, 0, gameWidth, gameHeight);

    ctx.fillStyle = winnerSnake.color;
    ctx.font = 'italic bold 30px sans-serif';
    ctx.textBaseline = 'bottom';
    ctx.fillText(winnerSnake.name + ' wins this game!', 20, gameHeight / 2 + 15);

    ctxMain.drawImage(textCanvas, 0, 0);
}

// uruchomienie nowej rundy
function StartNewRound() {
    deadSnakes = new Array();
    for (var i = 0; i < snakesNumber; i++) {
        snakes[i].resetSnake();
    }
    CleanColisionTable();
    ResetBonuses();
    ctxMain.clearRect(0, 0, gameWidth, gameHeight);
    $('.roundPoints').each(function() {$(this).text("")});
}

//dodanie punktów dla żyjących wężyków
function UpdatePoints() {
    for (var i = 0; i < snakesNumber; i++) {
        if (snakes[i].alive) {
            snakes[i].points += 1;
            snakes[i].roundPoints += 1;
        }
        $('#points' + i).text(snakes[i].points);
        $('#roundPoints' + i).text("+" + snakes[i].roundPoints);
    }
    $("#playersScoreTable").tablesorter({ sortList: [[1, 1]] });
    ChangeGoalColor();
}

function ChangeGoalColor() {
    var color = $("#playersScoreTable td").first().css('color'); // kolor aktualnego lidera
    $('#goalScore').css('background-color', color);
}

// sprawdza czy koniec gry. Jak tak to zwraca true, w przeciwnym wypadku false
function CheckGameEnd() {
    var newSnakes = snakes.slice(); // skopiowanie tablicy wezykow w celu posortowania (zeby nie zaburzyc pierwotnego porzadku)
    newSnakes.sort(function (a, b) { return b.points - a.points }); // posortowanie tablicy malejaco po ilosci punktow

    // koniec gry, osiagniety cel punktowy
    if (newSnakes.length >= 2) {
        if (newSnakes[0].points >= goal) {
            if (newSnakes[0].points - newSnakes[1].points >= 2) {
                winnerSnake = newSnakes[0];
                DrawEndText();
                return true;
            }
            // TIE BREAK
            else if (newSnakes[0].points == newSnakes[1].points) {
                goal += 2;
            }
            else {
                goal += 1;
            }
            $('#goalScore').text(goal);
            $('#toGet').text('Tie Break');
        }
        // TIE BREAK
        else if ((newSnakes[0].points == newSnakes[1].points && newSnakes[0].points == goal - 1)) {
            goal += 2;
            $('#goalScore').text(goal);
            $('#toGet').text('Tie Break');
        }
    }

    return false;
}

function FindRoundWinner() {
    if (snakesNumber == 1)
        winnerSnake = snakes[0];
    else {
        // jezeli dwoch zginelo jednoczesnie, to ten ktory zginal teoretycznie pozniej jest usuwany z listy martwych
        if (deadSnakes.length == snakesNumber) {
            deadSnakes.pop();
        }

        for (var i = 0; i < snakesNumber; i++) {
            if (!deadSnakes.contains(snakes[i].number))
                winnerSnake = snakes[i];
        }
    }
}

// OBSŁUGA KLAWISZY
function KeyUp(e) {
    for (var i = 0; i < snakesNumber; i++) {
        // strzałka w lewo
        if (e.keyCode == snakes[i].leftKey) {
            snakes[i].leftKeyPressed = false;
            snakes[i].leftKeyPressedFirstTime = true;
        }
        // strzałka w prawo
        if (e.keyCode == snakes[i].rightKey) {
            snakes[i].rightKeyPressed = false;
            snakes[i].rightKeyPressedFirstTime = true;
        }
    }
}
function KeyDown(e) {
    for (var i = 0; i < snakesNumber; i++) {
        // strzałka w lewo
        if (e.keyCode == snakes[i].leftKey) {
            snakes[i].leftKeyPressed = true;
        }
            // strzałka w prawo
        else if (e.keyCode == snakes[i].rightKey) {
            snakes[i].rightKeyPressed = true;
        }
    }
}